/**
 * Toast 服务
 * 提供全局可用的消息提示功能
 * @author LYC
 * @date 2025-09-21
 */
import { createVNode, render, App, Component } from 'vue'
import ToastComponent from './Toast.vue'

export interface ToastOptions {
  message: string
  title?: string
  type?: 'success' | 'error' | 'warning' | 'info'
  duration?: number
  showIcon?: boolean
}

interface ToastInstance {
  createToast: (options: ToastOptions) => void
  success: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => void
  error: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => void
  info: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => void
  warning: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => void
  clearAllToasts: () => void
}

// Toast 实例引用
let toastInstance: ToastInstance | null = null
let mountNode: HTMLElement | null = null

// 创建并挂载 Toast 组件
const createToastInstance = (): ToastInstance => {
  // 先确保清理之前的挂载
  if (mountNode && document.body.contains(mountNode)) {
    document.body.removeChild(mountNode)
  }

  // 创建一个新的挂载点
  mountNode = document.createElement('div')
  mountNode.setAttribute('id', 'toast-container')
  mountNode.setAttribute('style', 'z-index:9999; position:relative;')
  document.body.appendChild(mountNode)

  // 创建 vnode
  const vnode = createVNode(ToastComponent)
  render(vnode, mountNode)

  // 返回实例方法
  if (!vnode.component?.exposed) {
    throw new Error('Toast component initialization failed')
  }

  return vnode.component.exposed as ToastInstance
}

// 确保有 Toast 实例
const ensureInstance = (): ToastInstance => {
  if (!toastInstance) {
    toastInstance = createToastInstance()
  }
  return toastInstance
}

// 导出的 Toast 对象
export const Toast = {
  install(app: App): void {
    // 确保只有一个实例
    const instance = ensureInstance()

    // 全局属性
    app.config.globalProperties.$toast = {
      show: instance.createToast,
      success: instance.success,
      error: instance.error,
      info: instance.info,
      warning: instance.warning,
      clear: instance.clearAllToasts
    }

    // 全局组件
    app.component('Toast', ToastComponent as Component)
  },

  // 直接调用方法
  show(options: ToastOptions): void {
    ensureInstance().createToast(options)
  },

  success(message: string, options?: Omit<ToastOptions, 'message' | 'type'>): void {
    ensureInstance().success(message, options)
  },

  error(message: string, options?: Omit<ToastOptions, 'message' | 'type'>): void {
    ensureInstance().error(message, options)
  },

  info(message: string, options?: Omit<ToastOptions, 'message' | 'type'>): void {
    ensureInstance().info(message, options)
  },

  warning(message: string, options?: Omit<ToastOptions, 'message' | 'type'>): void {
    ensureInstance().warning(message, options)
  },

  clear(): void {
    if (toastInstance) {
      toastInstance.clearAllToasts()
    }
  }
}

// 导出类型
export type { ToastInstance }

// 声明 Vue 全局属性
declare module '@vue/runtime-core' {
  export interface ComponentCustomProperties {
    $toast: {
      show: (options: ToastOptions) => void
      success: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => void
      error: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => void
      info: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => void
      warning: (message: string, options?: Omit<ToastOptions, 'message' | 'type'>) => void
      clear: () => void
    }
  }
}

// 默认导出
export default Toast
